package com.ruoyi.system.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysFile;
import com.ruoyi.system.domain.SysOrder;
import com.ruoyi.system.domain.SysOrderLog;
import com.ruoyi.system.domain.SysOrderDept;
import com.ruoyi.system.domain.excel.OrderModelExcel;
import com.ruoyi.system.service.*;
import com.ruoyi.system.vo.req.AnalyExcelReqVO;
import com.ruoyi.system.vo.resp.AnalysisRespVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.rmi.ServerException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author xdh
 * @title SysExcelserviceImpl
 * @date 2024/7/1 14:09
 * @description TODO
 */

@Service
@Slf4j
public class SysExcelserviceImpl implements SysExcelservice {

    @Autowired
    private SysOrderLogService sysOrderLogService;

    @Autowired
    private SysOrderService sysOrderService;

    @Autowired
    private SysOrderDeptService sysOrderUserService;

    @Autowired
    private TokenService tokenService;


    @Autowired
    private RemoteFileService remoteFileService;


    @Autowired
    private SysOrderSpeedService sysOrderSpeedService;

    @Transactional(rollbackFor = Exception.class)
    public Long analysisExcel(MultipartFile file) throws IOException {

            SysDept dept = tokenService.getLoginUser().getSysUser().getDept();
            if(dept == null){
                throw  new ServiceException("当前用户未分配组织！");
            }
            if(dept.getDeptLevel() != 1){
                throw  new ServiceException("非市级单位，无法进行数据导入！");
            }

            R<SysFile> upload = remoteFileService.upload(file);

            if(upload.getCode() != 200){
                throw new ServiceException("文件上传失败！");
            }

            File convert = FileUtils.convert(file);
//            File file = new File(filePath);
//            if (!file.exists()) {
//                throw new RuntimeException("文件不存在");
//            }
          try {
            List<OrderModelExcel> orders = EasyExcel.read(convert)
                    .head(OrderModelExcel.class)
                    .sheet()
                    .doReadSync();




            if(orders.isEmpty()){
                throw new ServiceException("文件内容为空！");
            }

            Long unid = null;

            Date date = new Date();
            //新增数据到记录表
            for (OrderModelExcel order : orders) {
                SysOrderLog sysOrder = new SysOrderLog();
                sysOrder.setOrderCode(order.getOrder_code());
                sysOrder.setOrderBuyerName(order.getOrder_buyer_name());
                sysOrder.setOrderBuyerIndo(order.getOrder_buyer_indo());
                sysOrder.setOrderBuyerTel(order.getOrder_buyer_tel());
                sysOrder.setOrderTime(order.getOrder_time());
                //sysOrder.setOrderTime(DateUtils.parseDate(order.getOrder_time(), "yyyy-MM-dd HH:mm:ss"));
                sysOrder.setOrderGoods(order.getOrder_goods());
                sysOrder.setOrderHarverName(order.getOrder_harver_name());
                sysOrder.setOrderHarverTel(order.getOrder_harver_tel());
                sysOrder.setOrderHarverAddress(order.getOrder_harver_address());
                sysOrder.setOrderStatus(1);
                unid = date.getTime();
                sysOrder.setOrderCretime(date);
                sysOrder.setOrderBatchno(unid);
                sysOrder.setIsValidtime(0);
                sysOrder.setIsValidtel(0);
                sysOrder.setIsValididno(0);
                sysOrder.setOrderDataStatus(0);
                sysOrder.setIsRepeat(0);
                if(!isValidTime(order.getOrder_time())){
                    sysOrder.setIsValidtime(1);
                }else if(!isValidTel(order.getOrder_buyer_tel())){
                    sysOrder.setIsValidtel(1);
                }else if(isValidIdNo(order.getOrder_buyer_indo())){
                    sysOrder.setIsValididno(1);
                }else{
                    sysOrder.setOrderDataStatus(1);
                }
                //判断重复数据
                int count = sysOrderService.count(new LambdaQueryWrapper<SysOrder>().eq(SysOrder::getOrderStatus, 1)
                        .eq(SysOrder::getOrderCode, order.getOrder_code()));
                if(count > 0){
                    sysOrder.setIsRepeat(1);
                }
                sysOrderLogService.save(sysOrder);

            }
            List<SysOrderLog> list = sysOrderLogService.list(new LambdaQueryWrapper<SysOrderLog>()
                    .eq(SysOrderLog::getOrderBatchno, unid).eq(SysOrderLog::getOrderStatus, 1));
            if(!list.isEmpty()){
                //判断是否重复
                HashMap<SysOrderLog, Integer> map = new HashMap<>();

                for (SysOrderLog order : list) {
                    map.put(order, map.getOrDefault(order, 0) + 1);
                }

                // 筛选出重复数据
                List<SysOrderLog> duplicateOrders = map.entrySet().stream()
                        .filter(entry -> entry.getValue() > 1)
                        .map(Map.Entry::getKey)
                        .collect(Collectors.toList());

                for (SysOrderLog duplicateOrder : duplicateOrders) {
                    duplicateOrder.setIsRepeat(1);
                    sysOrderLogService.updateById(duplicateOrder);
                }


            }
            return unid;
          }catch (Exception e){
              throw  new ServerException("上传文件格式不合法！");
          }


    }

    @Override
    public AnalysisRespVO page(AnalyExcelReqVO dto) {

        AnalysisRespVO analysisRespVO = new AnalysisRespVO();

        IPage<SysOrderLog> objectPage = new Page<>(dto.getPageNum(), dto.getPageSize());
        IPage<SysOrderLog> postPage = sysOrderLogService.page(objectPage,
                new LambdaQueryWrapper<SysOrderLog>()
                        .eq(SysOrderLog::getOrderBatchno, dto.getUnid()).eq(SysOrderLog::getOrderStatus,1)
                        .orderByAsc(SysOrderLog::getOrderTime));


        analysisRespVO.setPage(postPage);
        List<SysOrderLog> list = sysOrderLogService.list(
                new LambdaQueryWrapper<SysOrderLog>().select(SysOrderLog::getOrderDataStatus,SysOrderLog::getIsRepeat)
                        .eq(SysOrderLog::getOrderStatus, 1).eq(SysOrderLog::getOrderBatchno, dto.getUnid()));

        Integer repeat_num = sysOrderLogService.count(new LambdaQueryWrapper<SysOrderLog>()
                .eq(SysOrderLog::getOrderBatchno, dto.getUnid()).eq(SysOrderLog::getOrderStatus, 1).eq(SysOrderLog::getIsRepeat, 1));

        Map<Integer, List<SysOrderLog>> map
                = list.stream().collect(Collectors.groupingBy(s -> s.getOrderDataStatus()));
        //重复数据不属于异常数据
        List<SysOrderLog> orDefault = map.getOrDefault(1, new ArrayList<SysOrderLog>());
        Long count = orDefault.stream().filter(s -> s.getIsRepeat() != 1).count();
        analysisRespVO.setNormal_num(count.intValue());
        analysisRespVO.setAbnormal_num(map.getOrDefault(0,new ArrayList<SysOrderLog>()).size());
        analysisRespVO.setRepeat_num(repeat_num);
        return analysisRespVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean del(Integer orderId) {
        SysOrderLog sysOrderLog = new SysOrderLog();
        sysOrderLog.setOrderStatus(0);
        sysOrderLog.setOrderId(orderId);
        return  sysOrderLogService.updateById(sysOrderLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean save(Long unid) {
        if(unid == null){
            throw new ServiceException("业务id不能为空！");
        }

        SysDept dept = tokenService.getLoginUser().getSysUser().getDept();

        if(dept == null){
            throw  new ServiceException("当前用户未分配组织");
        }

        List<SysOrderLog> list = sysOrderLogService.
                list(new LambdaQueryWrapper<SysOrderLog>()
                        .eq(SysOrderLog::getOrderStatus, 1).eq(SysOrderLog::getOrderBatchno, unid)
                        .eq(SysOrderLog::getOrderDataStatus,1).eq(SysOrderLog::getIsRepeat,0));

        if(!list.isEmpty()){
            for (SysOrderLog sysOrderLog : list) {
                SysOrder sysOrder = new SysOrder();
                sysOrder.setOrderCode(sysOrderLog.getOrderCode());
                sysOrder.setOrderBuyerName(sysOrderLog.getOrderBuyerName());
                sysOrder.setOrderBuyerIndo(sysOrderLog.getOrderBuyerIndo());
                sysOrder.setOrderBuyerTel(sysOrderLog.getOrderBuyerTel());
                sysOrder.setOrderTime(sysOrderLog.getOrderTime());
                sysOrder.setOrderGoods(sysOrderLog.getOrderGoods());
                sysOrder.setOrderHarverName(sysOrderLog.getOrderHarverName());
                sysOrder.setOrderHarverTel(sysOrderLog.getOrderHarverTel());
                sysOrder.setOrderHarverAddress(sysOrderLog.getOrderHarverAddress());
                sysOrder.setOrderStatus(sysOrderLog.getOrderStatus());
                sysOrder.setOrderStatusMsg(sysOrderLog.getOrderStatusMsg());
                sysOrder.setOrderCretime(sysOrderLog.getOrderCretime());
                sysOrder.setOrderBatchno(sysOrderLog.getOrderBatchno());
                sysOrder.setOrderLogId(sysOrderLog.getOrderId());
                sysOrderService.save(sysOrder);


                SysOrderDept sysOrderUser = new SysOrderDept();
                sysOrderUser.setOrderId(sysOrder.getId());
                sysOrderUser.setDeptId(dept.getDeptId());
                sysOrderUser.setStatus(1);
                sysOrderUser.setCreTime(new Date());
                sysOrderUser.setOrderStatus(1); //待分发
                sysOrderUser.setDeptPid(0l);
                sysOrderUserService.save(sysOrderUser);

                sysOrderSpeedService.createOrder(sysOrder.getId());
            }
            return true;
        }
        throw new ServiceException("正常订单总计0条，导入失败！");

    }


    // 校验时间格式（假设格式为 yyyy-MM-dd HH:mm:ss）
    private boolean isValidTime(String time) {
        return Pattern.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", time);
    }

    // 校验联系方式（假设为 11 位手机号）
    private boolean isValidTel(String tel) {
        return Pattern.matches("\\d{11}", tel);
    }

    // 校验身份证号码（假设为 18 位）
//    private boolean isValidIdNo(String idNo) {
//        return Pattern.matches("\\d{18}", idNo);
//    }

    // 校验身份证号码（假设为 18 位）
    public static boolean isValidIdNo(String id) {
        String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9Xx])$";
        if (id.matches(regex)) {
            // 检验校验码的方法
            return isValidCheckCode(id);
        }
        return false;
    }

    private static boolean isValidCheckCode(String id) {
        int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] checkCode = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += (id.charAt(i) - '0') * weights[i];
        }
        return checkCode[sum % 11] == id.charAt(17);
    }
}
